package com.sec.android.app.myfiles;

import com.samsung.android.sdk.slinkcloud.CloudGatewaySignInUtils;
import com.sec.android.app.myfiles.info.AppFeatures;
import com.sec.android.app.myfiles.info.SccFileUtil;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.provider.PrivateMyFilesProvider;
import com.sec.android.app.myfiles.shadow.android.ShadowAccessibilityManager;
import com.sec.android.app.myfiles.shadow.android.ShadowContentResolver;
import com.sec.android.app.myfiles.shadow.android.ShadowContextCompat;
import com.sec.android.app.myfiles.shadow.android.ShadowDebug;
import com.sec.android.app.myfiles.shadow.android.ShadowDrmInfoRequest;
import com.sec.android.app.myfiles.shadow.android.ShadowDrmManagerClient;
import com.sec.android.app.myfiles.shadow.android.ShadowEnvironment;
import com.sec.android.app.myfiles.shadow.android.ShadowMediaMetadataRetriever;
import com.sec.android.app.myfiles.shadow.android.ShadowStatFs;
import com.sec.android.app.myfiles.shadow.android.ShadowStorageManager;
import com.sec.android.app.myfiles.shadow.android.ShadowStorageVolumeUtil;
import com.sec.android.app.myfiles.shadow.android.ShadowToast;
import com.sec.android.app.myfiles.shadow.custom.ShadowAppFeatures;
import com.sec.android.app.myfiles.shadow.custom.ShadowCloudGatewaySignInUtils;
import com.sec.android.app.myfiles.shadow.custom.ShadowMyFilesLog;
import com.sec.android.app.myfiles.shadow.custom.ShadowMyFilesProvider;
import com.sec.android.app.myfiles.shadow.custom.ShadowSccFileUtil;
import com.sec.android.app.myfiles.shadow.custom.ShadowSecApiWrapper;
import com.sec.android.app.myfiles.shadow.custom.ShadowSemFwWrapper;
import com.sec.android.app.myfiles.shadow.sem.ShadowSemPrivateModeManager;
import com.sec.android.app.myfiles.util.SecApiWrapper;
import com.sec.android.app.myfiles.util.StorageVolumeUtil;

import org.apache.maven.artifact.ant.DependenciesTask;
import org.apache.maven.artifact.ant.RemoteRepository;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.internal.bytecode.InstrumentationConfiguration;
import org.robolectric.internal.bytecode.ShadowMap;
import org.robolectric.internal.dependency.DependencyResolver;
import org.robolectric.internal.dependency.MavenDependencyResolver;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.res.Fs;

/**
 * Created by jaebae on 2016-06-30.
 */
public class MyFilesTestRunner extends RobolectricTestRunner {
    private static final String BUILD_OUTPUT = "/build/intermediates";

    private static final Class[] CUSTOM_SHADOW_CLASS = {
            /*android class*/
            ShadowDebug.class,
            ShadowEnvironment.class,
            ShadowMediaMetadataRetriever.class,
            ShadowStorageManager.class,
            ShadowSemPrivateModeManager.class,
            ShadowContentResolver.class,
            ShadowAccessibilityManager.class,
            ShadowStatFs.class,
            ShadowDrmManagerClient.class,
            ShadowDrmInfoRequest.class,
            ShadowToast.class,
            ShadowContextCompat.class,

            /*SEP class*/

            /*custom class*/
            ShadowAppFeatures.class,
            ShadowMyFilesLog.class,
            ShadowSemFwWrapper.class,
            ShadowStorageVolumeUtil.class,
            ShadowSccFileUtil.class,
            ShadowCloudGatewaySignInUtils.class,
            ShadowSecApiWrapper.class,
            ShadowMyFilesProvider.class,
    };

    private static final String[] CUSTOM_INSTRUMENTED_CLASS_NAME = {
            AppFeatures.class.getName(),
            Log.class.getName(),
            StorageVolumeUtil.class.getName(),
            SccFileUtil.class.getName(),
            CloudGatewaySignInUtils.class.getName(),
            SecApiWrapper.class.getName(),
            PrivateMyFilesProvider.class.getName()
    };

    public MyFilesTestRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    public InstrumentationConfiguration createClassLoaderConfig(Config config) {
        InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder().withConfig(config);
        for (String s : CUSTOM_INSTRUMENTED_CLASS_NAME) {
            builder.addInstrumentedClass(s);
        }
        return builder.build();
    }

    @Override
    protected ShadowMap createShadowMap() {
        final ShadowMap.Builder builder = super.createShadowMap().newBuilder();
        for (Class klass : CUSTOM_SHADOW_CLASS) {
            builder.addShadowClass(klass);
        }
        return builder.build();
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String path = BuildConfig.class.getResource("").toString().replace("file:", "").replace("jar:", "");
        path = path.substring(0, path.lastIndexOf("/build"));
        String manifestName = path + "/src/test/AndroidManifest.xml";
        String type = BuildConfig.BUILD_TYPE;

        return new AndroidManifest(
                Fs.fileFromPath(manifestName),
                Fs.fileFromPath(path + BUILD_OUTPUT + "/res/merged/" + type),
                Fs.fileFromPath(path + "/assets"));
    }

    @Override
    protected DependencyResolver getJarResolver() {
        return new ProxyDependencyResolver();
    }

    private static class ProxyDependencyResolver extends MavenDependencyResolver {

        @Override
        protected void configureMaven(DependenciesTask dependenciesTask) {
            RemoteRepository remoteRepository = new RemoteRepository();
            remoteRepository.setId("sonatype");
            remoteRepository.setUrl("http://repo1.maven.org/maven2");

            super.configureMaven(dependenciesTask);
            dependenciesTask.addConfiguredRemoteRepository(remoteRepository);
        }
    }
}
